#include "MyRpc/message.h"
namespace myrpc
{

  Message::Message(uint64_t message_size)
      : func_vec_(),
        head_size_(4),
        rpc_()
  {
    func_vec_.resize(base::Dataformat::data_type_size_ + 1);
    Init_rpc();
  };
  bool Message::Init_message(uint32_t type, message_func func)
  {
    if (base::Dataformat::Data_type_is_available(type))
    {
      func_vec_[type] = std::move(func);
      return true;
    }
    else
    {
      return false;
    }
  };

  void Message::Init_rpc()
  {
    Init_message(static_cast<uint32_t>(4), [this](net_tools::net::Connect *connect, char *buf, unsigned int) -> unsigned int
                 { return rpc_.Call_fun(connect, buf); });
  };
  base::Rpc *Message::Get_rpc()
  {
    return &rpc_;
  };
  uint Message::Consume_message(net_tools::net::Connect *connect, char *buf, uint size)
  {
    if (size >= head_size_) [[likely]]
    {
      int already_consume = 0;
      uint32_t type = Analyze_head(buf);
      already_consume += head_size_;
      if (!func_vec_[type])
      {
        return -1;
      }
      else
      {
        already_consume += (func_vec_[type])(connect, buf + head_size_, size - head_size_);
      }
      return already_consume;
    }
    else
    {
      return 0;
    }
  };
  uint32_t Message::Analyze_head(char *buf)
  {
    return *reinterpret_cast<uint32_t *>(buf);
  };
  void Message::Creat_head(uint32_t type, char *buf)
  {
    uint32_t *head = reinterpret_cast<uint32_t *>(buf);
    *head = type;
  };

} // namespace myrpc